import pandas as pd
import json
import matplotlib.pyplot as plt
import matplotlib
from collections import Counter
import re
import requests
import base64
import hashlib

# 设置中文字体支持
matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
matplotlib.rcParams['axes.unicode_minus'] = False

def parse_envoy_request_body(request_headers_str):
    """从request_headers字符串中解析envoy.lua:request_body，返回解析后的数据"""
    try:
        # 尝试解析JSON
        request_headers = json.loads(request_headers_str)
        
        # 获取envoy.lua:request_body
        if 'envoy.lua:request_body' in request_headers:
            request_body_str = request_headers['envoy.lua:request_body']
            
            # 处理截断的JSON字符串
            if '<truncated>' in request_body_str:
                # 如果有截断，尝试修复JSON或直接用正则表达式
                return parse_with_regex(request_headers_str)
            
            # 解析request_body JSON字符串
            request_body = json.loads(request_body_str)
            
            # 返回完整的request_body数据，用于后续分析
            return request_body
                
    except (json.JSONDecodeError, KeyError, TypeError) as e:
        # 如果JSON解析失败，尝试正则表达式提取所有信息
        return parse_with_regex(request_headers_str)
    
    return None

def parse_with_regex(request_headers_str):
    """使用正则表达式解析所有关键信息"""
    try:
        result = {}
        
        # 提取transmitReason
        transmit_reason_pattern = r'"transmitReason":"([^"]*)"'
        transmit_reason_match = re.search(transmit_reason_pattern, request_headers_str)
        if transmit_reason_match:
            result['transmitReason'] = transmit_reason_match.group(1)
        
        # 提取transmitDoctorName
        doctor_name_pattern = r'"transmitDoctorName":"([^"]*)"'
        doctor_name_match = re.search(doctor_name_pattern, request_headers_str)
        if doctor_name_match:
            result['transmitDoctorName'] = doctor_name_match.group(1)
        
        # 提取thirdLoginName
        third_login_pattern = r'"thirdLoginName":"([^"]*)"'
        third_login_match = re.search(third_login_pattern, request_headers_str)
        if third_login_match:
            result['thirdLoginName'] = third_login_match.group(1)
        
        # 创建假的rxInfoDto结构来提取药品信息
        drug_info_list = []
        
        # 使用正则表达式提取drugName
        drug_name_pattern = r'"drugName":"([^"]*)"'
        drug_name_matches = re.findall(drug_name_pattern, request_headers_str)
        
        for drug_name in drug_name_matches:
            if drug_name.strip():
                drug_info_list.append({'drugName': drug_name.strip()})
        
        if drug_info_list:
            result['rxInfoDto'] = {'drugInfoList': drug_info_list}
        
        return result if result else None
        
    except Exception as e:
        print(f"正则表达式解析错误: {e}")
        return None

def extract_drug_info(parsed_data):
    """从解析后的数据中提取药品信息"""
    drug_names = []
    if parsed_data and 'rxInfoDto' in parsed_data:
        rx_info = parsed_data['rxInfoDto']
        if 'drugInfoList' in rx_info and isinstance(rx_info['drugInfoList'], list):
            for drug in rx_info['drugInfoList']:
                if isinstance(drug, dict) and 'drugName' in drug:
                    drug_name = drug['drugName'].strip()
                    if drug_name:
                        drug_names.append(drug_name)
    return drug_names

def debug_extract_drug_info(parsed_data):
    """调试版本的药品提取函数"""
    debug_info = {
        'has_parsed_data': parsed_data is not None,
        'has_rxInfoDto': False,
        'has_drugInfoList': False,
        'drugInfoList_type': None,
        'drugInfoList_length': 0,
        'drug_names': []
    }
    
    if parsed_data:
        debug_info['has_rxInfoDto'] = 'rxInfoDto' in parsed_data
        if 'rxInfoDto' in parsed_data:
            rx_info = parsed_data['rxInfoDto']
            debug_info['has_drugInfoList'] = 'drugInfoList' in rx_info
            if 'drugInfoList' in rx_info:
                debug_info['drugInfoList_type'] = type(rx_info['drugInfoList'])
                if isinstance(rx_info['drugInfoList'], list):
                    debug_info['drugInfoList_length'] = len(rx_info['drugInfoList'])
                    for drug in rx_info['drugInfoList']:
                        if isinstance(drug, dict) and 'drugName' in drug:
                            drug_name = drug['drugName'].strip()
                            if drug_name:
                                debug_info['drug_names'].append(drug_name)
    
    return debug_info

def send_image_to_wechat_webhook(image_path, webhook_url, title="分析结果图表"):
    """发送图片到企业微信群"""
    try:
        # 读取图片文件
        with open(image_path, 'rb') as f:
            image_data = f.read()
        
        # 将图片转换为base64
        image_base64 = base64.b64encode(image_data).decode('utf-8')
        
        # 计算图片的md5
        image_md5 = hashlib.md5(image_data).hexdigest()
        
        # 构造消息体
        message = {
            "msgtype": "image",
            "image": {
                "base64": image_base64,
                "md5": image_md5
            }
        }
        
        # 发送请求
        response = requests.post(
            webhook_url,
            json=message,
            headers={'Content-Type': 'application/json'}
        )
        
        if response.status_code == 200:
            result = response.json()
            if result.get('errcode') == 0:
                print(f"✅ 成功发送图片: {image_path}")
                return True
            else:
                print(f"❌ 发送失败: {result.get('errmsg', '未知错误')}")
                return False
        else:
            print(f"❌ HTTP请求失败: {response.status_code}")
            return False
            
    except Exception as e:
        print(f"❌ 发送图片时出错: {e}")
        return False

def send_text_to_wechat_webhook(text, webhook_url):
    """发送文本消息到企业微信群"""
    try:
        message = {
            "msgtype": "text",
            "text": {
                "content": text
            }
        }
        
        response = requests.post(
            webhook_url,
            json=message,
            headers={'Content-Type': 'application/json'}
        )
        
        if response.status_code == 200:
            result = response.json()
            if result.get('errcode') == 0:
                print("✅ 成功发送文本消息")
                return True
            else:
                print(f"❌ 发送失败: {result.get('errmsg', '未知错误')}")
                return False
        else:
            print(f"❌ HTTP请求失败: {response.status_code}")
            return False
            
    except Exception as e:
        print(f"❌ 发送文本时出错: {e}")
        return False

def create_doctor_analysis_chart(doctor_counter, top_reason, total_records):
    """创建医生账号分析图表"""
    # 获取前10个医生账号
    top_doctors = doctor_counter.most_common(10)
    if not top_doctors:
        return
    
    doctors = [item[0] for item in top_doctors]
    counts = [item[1] for item in top_doctors]
    
    # 截断过长的医生名称
    short_doctors = []
    for doctor in doctors:
        if len(doctor) > 20:
            short_doctors.append(doctor[:17] + '...')
        else:
            short_doctors.append(doctor)
    
    # 创建医生账号分析图表
    plt.figure(figsize=(14, 10))
    
    # 创建柱状图
    plt.subplot(2, 1, 1)
    colors = plt.cm.Set1(range(len(counts)))
    bars = plt.bar(range(len(short_doctors)), counts, color=colors)
    
    # 添加数值标签
    for i, (bar, count) in enumerate(zip(bars, counts)):
        plt.text(i, count + max(counts) * 0.01, str(count), 
                ha='center', va='bottom', fontweight='bold')
    
    plt.xlabel('医生账号')
    plt.ylabel('次数')
    plt.title(f'"{top_reason}" 的医生账号分布 (前10名)', fontsize=14, fontweight='bold')
    plt.xticks(range(len(short_doctors)), short_doctors, rotation=45, ha='right')
    plt.grid(axis='y', alpha=0.3)
    
    # 创建水平柱状图（更适合显示长名称）
    plt.subplot(2, 1, 2)
    bars = plt.barh(range(len(short_doctors)), counts, color=colors)
    
    # 添加数值标签
    for i, (bar, count) in enumerate(zip(bars, counts)):
        percentage = (count / total_records) * 100
        plt.text(count + max(counts) * 0.01, i, f'{count} ({percentage:.1f}%)', 
                va='center', ha='left', fontweight='bold')
    
    plt.xlabel('次数')
    plt.ylabel('医生账号')
    plt.title(f'"{top_reason}" 的医生账号占比分析', fontsize=14, fontweight='bold')
    plt.yticks(range(len(short_doctors)), short_doctors)
    plt.gca().invert_yaxis()
    plt.grid(axis='x', alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('doctor_analysis_chart.png', dpi=300, bbox_inches='tight')
    print("医生账号分析图表已保存为 'doctor_analysis_chart.png'")
    plt.show()

def analyze_drug_distribution_for_risk_detection(clean_df):
    """分析风险检测不通过的药品分布"""
    print(f"\n分析'风险检测不通过'的药品分布:")
    print("=" * 50)
    
    # 筛选出"风险检测不通过"的数据（包含各种空格变体）
    risk_pattern = clean_df['transmitReason'].str.contains('风.*险.*检测.*不.*通过', na=False)
    risk_data = clean_df[risk_pattern]
    
    if len(risk_data) == 0:
        print("未找到'风险检测不通过'的数据")
        return
    
    print(f"'风险检测不通过'记录总数: {len(risk_data)} 条")
    
    # 收集所有药品
    all_drugs = []
    records_with_drugs = 0
    
    # 添加调试信息 - 查看前5条记录
    debug_count = 0
    for _, row in risk_data.iterrows():
        drug_names = row.get('drug_names', [])
        
        # 调试前5条记录
        if debug_count < 5:
            print(f"\n调试记录 {debug_count + 1}:")
            print(f"  transmitReason: {row['transmitReason']}")
            print(f"  drug_names: {drug_names}")
            debug_count += 1
        
        if drug_names:
            records_with_drugs += 1
            all_drugs.extend(drug_names)
    
    print(f"包含药品信息的记录: {records_with_drugs} 条")
    print(f"涉及药品总数: {len(all_drugs)} 个")
    
    if not all_drugs:
        print("未找到药品信息")
        return
    
    # 统计药品分布
    drug_counter = Counter(all_drugs)
    unique_drugs = len(drug_counter)
    
    print(f"不同药品种类: {unique_drugs} 种")
    print(f"\n药品排行榜 (前40名):")
    print("-" * 60)
    
    for i, (drug, count) in enumerate(drug_counter.most_common(40), 1):
        percentage = (count / len(all_drugs)) * 100
        print(f"{i:2d}. {drug}: {count} 次 ({percentage:.1f}%)")
    
    # 保存药品分析报告
    with open('risk_drug_analysis.txt', 'w', encoding='utf-8') as f:
        f.write("'风险检测不通过' 药品分布分析\n")
        f.write("=" * 50 + "\n\n")
        f.write(f"分析记录总数: {len(risk_data)} 条\n")
        f.write(f"包含药品信息的记录: {records_with_drugs} 条\n")
        f.write(f"涉及药品总数: {len(all_drugs)} 个\n")
        f.write(f"不同药品种类: {unique_drugs} 种\n\n")
        f.write("完整药品排行榜:\n")
        f.write("-" * 40 + "\n")
        
        for i, (drug, count) in enumerate(drug_counter.most_common(), 1):
            percentage = (count / len(all_drugs)) * 100
            f.write(f"{i:3d}. {drug}: {count} 次 ({percentage:.1f}%)\n")
    
    print("\n详细药品分析已保存为 'risk_drug_analysis.txt'")
    
    # 创建药品分析图表
    create_drug_analysis_chart(drug_counter, len(all_drugs))

def create_drug_analysis_chart(drug_counter, total_drugs):
    """创建药品分析图表"""
    # 获取前20个药品
    top_drugs = drug_counter.most_common(20)
    if not top_drugs:
        return
    
    drugs = [item[0] for item in top_drugs]
    counts = [item[1] for item in top_drugs]
    
    # 截断过长的药品名称
    short_drugs = []
    for drug in drugs:
        if len(drug) > 15:
            short_drugs.append(drug[:12] + '...')
        else:
            short_drugs.append(drug)
    
    # 创建药品分析图表
    plt.figure(figsize=(16, 12))
    
    # 创建饼图
    plt.subplot(2, 1, 1)
    colors = plt.cm.Set3(range(len(counts)))
    
    # 计算其他药品的数量
    other_count = sum(count for drug, count in drug_counter.most_common()[20:])
    if other_count > 0:
        drugs_for_pie = short_drugs + ['其他']
        counts_for_pie = counts + [other_count]
        colors = plt.cm.Set3(range(len(counts_for_pie)))
    else:
        drugs_for_pie = short_drugs
        counts_for_pie = counts
    
    plt.pie(counts_for_pie, labels=drugs_for_pie, autopct='%1.1f%%', 
            startangle=90, colors=colors, textprops={'fontsize': 8})
    plt.title('"风险检测不通过" 药品分布比例 (前20名)', fontsize=14, fontweight='bold')
    
    # 创建水平柱状图
    plt.subplot(2, 1, 2)
    bars = plt.barh(range(len(short_drugs)), counts, color=colors[:len(short_drugs)])
    
    # 添加数值标签
    for i, (bar, count) in enumerate(zip(bars, counts)):
        percentage = (count / total_drugs) * 100
        plt.text(count + max(counts) * 0.01, i, f'{count} ({percentage:.1f}%)', 
                va='center', ha='left', fontweight='bold', fontsize=9)
    
    plt.xlabel('次数')
    plt.ylabel('药品名称')
    plt.title('"风险检测不通过" 药品数量统计 (前20名)', fontsize=14, fontweight='bold')
    plt.yticks(range(len(short_drugs)), short_drugs)
    plt.gca().invert_yaxis()
    plt.grid(axis='x', alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('risk_drug_analysis_chart.png', dpi=300, bbox_inches='tight')
    print("药品分析图表已保存为 'risk_drug_analysis_chart.png'")
    plt.show()

def analyze_drug_distribution_for_diagnosis_issue(clean_df):
    """分析'诊断为其他，但这个药没有诊断'的药品分布"""
    print(f"\n分析'诊断为其他，但这个药没有诊断'的药品分布:")
    print("=" * 60)
    
    # 筛选出"诊断为其他，但这个药没有诊断"的数据
    diagnosis_pattern = clean_df['transmitReason'].str.contains('诊断为其他.*药.*诊断', na=False)
    diagnosis_data = clean_df[diagnosis_pattern]
    
    if len(diagnosis_data) == 0:
        print("未找到'诊断为其他，但这个药没有诊断'的数据")
        return
    
    print(f"'诊断为其他，但这个药没有诊断'记录总数: {len(diagnosis_data)} 条")
    
    # 收集所有药品
    all_drugs = []
    records_with_drugs = 0
    
    # 添加调试信息 - 查看前3条记录
    debug_count = 0
    for _, row in diagnosis_data.iterrows():
        drug_names = row.get('drug_names', [])
        
        # 调试前3条记录
        if debug_count < 3:
            print(f"\n调试记录 {debug_count + 1}:")
            print(f"  transmitReason: {row['transmitReason']}")
            print(f"  drug_names: {drug_names}")
            debug_count += 1
        
        if drug_names:
            records_with_drugs += 1
            all_drugs.extend(drug_names)
    
    print(f"包含药品信息的记录: {records_with_drugs} 条")
    print(f"涉及药品总数: {len(all_drugs)} 个")
    
    if not all_drugs:
        print("未找到药品信息")
        return
    
    # 统计药品分布
    drug_counter = Counter(all_drugs)
    unique_drugs = len(drug_counter)
    
    print(f"不同药品种类: {unique_drugs} 种")
    print(f"\n药品排行榜 (前30名):")
    print("-" * 60)
    
    for i, (drug, count) in enumerate(drug_counter.most_common(30), 1):
        percentage = (count / len(all_drugs)) * 100
        print(f"{i:2d}. {drug}: {count} 次 ({percentage:.1f}%)")
    
    # 保存药品分析报告
    with open('diagnosis_drug_analysis.txt', 'w', encoding='utf-8') as f:
        f.write("'诊断为其他，但这个药没有诊断' 药品分布分析\n")
        f.write("=" * 60 + "\n\n")
        f.write(f"分析记录总数: {len(diagnosis_data)} 条\n")
        f.write(f"包含药品信息的记录: {records_with_drugs} 条\n")
        f.write(f"涉及药品总数: {len(all_drugs)} 个\n")
        f.write(f"不同药品种类: {unique_drugs} 种\n\n")
        f.write("完整药品排行榜:\n")
        f.write("-" * 40 + "\n")
        
        for i, (drug, count) in enumerate(drug_counter.most_common(), 1):
            percentage = (count / len(all_drugs)) * 100
            f.write(f"{i:3d}. {drug}: {count} 次 ({percentage:.1f}%)\n")
    
    print("\n详细药品分析已保存为 'diagnosis_drug_analysis.txt'")
    
    # 创建药品分析图表
    create_diagnosis_drug_analysis_chart(drug_counter, len(all_drugs))

def create_diagnosis_drug_analysis_chart(drug_counter, total_drugs):
    """创建诊断问题的药品分析图表"""
    # 获取前15个药品
    top_drugs = drug_counter.most_common(15)
    if not top_drugs:
        return
    
    drugs = [item[0] for item in top_drugs]
    counts = [item[1] for item in top_drugs]
    
    # 截断过长的药品名称
    short_drugs = []
    for drug in drugs:
        if len(drug) > 15:
            short_drugs.append(drug[:12] + '...')
        else:
            short_drugs.append(drug)
    
    # 创建药品分析图表
    plt.figure(figsize=(16, 12))
    
    # 创建饼图
    plt.subplot(2, 1, 1)
    colors = plt.cm.Pastel1(range(len(counts)))
    
    # 计算其他药品的数量
    other_count = sum(count for drug, count in drug_counter.most_common()[15:])
    if other_count > 0:
        drugs_for_pie = short_drugs + ['其他']
        counts_for_pie = counts + [other_count]
        colors = plt.cm.Pastel1(range(len(counts_for_pie)))
    else:
        drugs_for_pie = short_drugs
        counts_for_pie = counts
    
    plt.pie(counts_for_pie, labels=drugs_for_pie, autopct='%1.1f%%', 
            startangle=90, colors=colors, textprops={'fontsize': 9})
    plt.title('"诊断为其他，但这个药没有诊断" 药品分布比例 (前15名)', fontsize=14, fontweight='bold')
    
    # 创建水平柱状图
    plt.subplot(2, 1, 2)
    bars = plt.barh(range(len(short_drugs)), counts, color=colors[:len(short_drugs)])
    
    # 添加数值标签
    for i, (bar, count) in enumerate(zip(bars, counts)):
        percentage = (count / total_drugs) * 100
        plt.text(count + max(counts) * 0.01, i, f'{count} ({percentage:.1f}%)', 
                va='center', ha='left', fontweight='bold', fontsize=9)
    
    plt.xlabel('次数')
    plt.ylabel('药品名称')
    plt.title('"诊断为其他，但这个药没有诊断" 药品数量统计 (前15名)', fontsize=14, fontweight='bold')
    plt.yticks(range(len(short_drugs)), short_drugs)
    plt.gca().invert_yaxis()
    plt.grid(axis='x', alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('diagnosis_drug_analysis_chart.png', dpi=300, bbox_inches='tight')
    print("诊断问题药品分析图表已保存为 'diagnosis_drug_analysis_chart.png'")
    plt.show()

def main():
    print("开始读取CSV文件...")
    
    # 读取CSV文件
    try:
        df = pd.read_csv('result.csv')
        print(f"成功读取CSV文件，共{len(df)}行数据")
    except Exception as e:
        print(f"读取CSV文件失败: {e}")
        return
    
    print("开始解析request_headers中的数据...")
    
    # 提取所有的数据
    extracted_data = []
    
    for index, row in df.iterrows():
        if index % 1000 == 0:
            print(f"已处理 {index}/{len(df)} 行")
            
        # result_2.csv使用不同的字段名
        request_headers = row.get('request_headers', '')
        
        if pd.notna(request_headers) and request_headers != '':
            parsed_data = parse_envoy_request_body(request_headers)
            if parsed_data and 'transmitReason' in parsed_data:
                # 提取药品信息
                drug_names = extract_drug_info(parsed_data)
                
                # 调试：检查前3条风险检测记录
                transmit_reason = parsed_data.get('transmitReason', '')
                if '风险' in transmit_reason and '检测' in transmit_reason and len(extracted_data) < 3:
                    print(f"\n调试提取阶段 - 记录 {len(extracted_data) + 1}:")
                    print(f"  transmitReason: {transmit_reason}")
                    print(f"  parsed_data keys: {list(parsed_data.keys()) if parsed_data else 'None'}")
                    if parsed_data and len(str(parsed_data)) < 1000:
                        print(f"  parsed_data: {parsed_data}")
                    debug_info = debug_extract_drug_info(parsed_data)
                    print(f"  调试信息: {debug_info}")
                
                # 提取关键信息
                record = {
                    'transmitReason': transmit_reason,
                    'transmitDoctorName': parsed_data.get('transmitDoctorName', ''),
                    'thirdLoginName': parsed_data.get('thirdLoginName', ''),
                    'timestamp': row.get('start_time', ''),
                    'path': row.get('path', ''),
                    'drug_names': drug_names  # 添加药品信息
                }
                extracted_data.append(record)
    
    print(f"成功提取到 {len(extracted_data)} 条有效数据")
    
    if not extracted_data:
        print("未找到任何有效数据")
        return
    
    # 数据清洗
    print("开始数据清洗...")
    
    # 创建DataFrame便于处理
    clean_df = pd.DataFrame(extracted_data)
    
    # 清洗transmitReason字段
    clean_df['transmitReason'] = clean_df['transmitReason'].str.strip()
    clean_df = clean_df[clean_df['transmitReason'] != '']
    
    # 清洗医生名称字段
    clean_df['transmitDoctorName'] = clean_df['transmitDoctorName'].str.strip()
    clean_df['thirdLoginName'] = clean_df['thirdLoginName'].str.strip()
    
    # 将drug_names列表转换为字符串以便去重
    clean_df['drug_names_str'] = clean_df['drug_names'].apply(lambda x: ','.join(x) if x else '')
    
    # 去除重复记录（排除drug_names列，使用drug_names_str）
    columns_for_dedup = [col for col in clean_df.columns if col != 'drug_names']
    before_dedup = len(clean_df)
    clean_df = clean_df.drop_duplicates(subset=columns_for_dedup)
    after_dedup = len(clean_df)
    
    # 删除临时的字符串列
    clean_df = clean_df.drop('drug_names_str', axis=1)
    
    print(f"数据清洗完成：去重前 {before_dedup} 条，去重后 {after_dedup} 条")
    
    # 提取transmitReason列表用于统计
    transmit_reasons = clean_df['transmitReason'].tolist()
    
    if not transmit_reasons:
        print("未找到任何transmitReason数据")
        return
    
    # 统计transmitReason的分布
    reason_counter = Counter(transmit_reasons)
    
    # 输出统计结果
    print("\ntransmitReason 统计结果:")
    print("-" * 50)
    for reason, count in reason_counter.most_common():
        percentage = (count / len(transmit_reasons)) * 100
        print(f"{reason}: {count} 次 ({percentage:.1f}%)")
    
    # 分析最高的transmitReason的医生账号分布
    top_reason = reason_counter.most_common(1)[0][0]
    print(f"\n分析最高的transmitReason '{top_reason}' 的医生账号分布:")
    print("=" * 60)
    
    # 筛选出最高reason的数据
    top_reason_data = clean_df[clean_df['transmitReason'] == top_reason]
    
    # 统计医生账号分布（使用thirdLoginName）
    doctor_accounts = []
    for _, row in top_reason_data.iterrows():
        doctor_name = row['thirdLoginName']
        if doctor_name and doctor_name.strip() != '':
            doctor_accounts.append(doctor_name.strip())
    
    if doctor_accounts:
        doctor_counter = Counter(doctor_accounts)
        print(f"涉及医生账号总数: {len(doctor_counter)} 个")
        print(f"'{top_reason}' 总记录数: {len(top_reason_data)} 条")
        print("\n医生账号排行榜 (前15名):")
        print("-" * 40)
        
        for i, (doctor, count) in enumerate(doctor_counter.most_common(15), 1):
            percentage = (count / len(top_reason_data)) * 100
            print(f"{i:2d}. {doctor}: {count} 次 ({percentage:.1f}%)")
        
        # 保存医生账号详细分析
        with open('doctor_analysis.txt', 'w', encoding='utf-8') as f:
            f.write(f"最高transmitReason '{top_reason}' 的医生账号分析\n")
            f.write("=" * 60 + "\n\n")
            f.write(f"总记录数: {len(top_reason_data)} 条\n")
            f.write(f"涉及医生账号数: {len(doctor_counter)} 个\n\n")
            f.write("完整医生账号排行榜:\n")
            f.write("-" * 40 + "\n")
            
            for i, (doctor, count) in enumerate(doctor_counter.most_common(), 1):
                percentage = (count / len(top_reason_data)) * 100
                f.write(f"{i:3d}. {doctor}: {count} 次 ({percentage:.1f}%)\n")
        
        print("\n详细医生账号分析已保存为 'doctor_analysis.txt'")
        
        # 为医生账号分析创建额外的图表
        create_doctor_analysis_chart(doctor_counter, top_reason, len(top_reason_data))
    else:
        print("未找到有效的医生账号信息")
    
    # 分析"风险检测不通过"的药品分布
    analyze_drug_distribution_for_risk_detection(clean_df)
    
    # 分析"诊断为其他，但这个药没有诊断"的药品分布
    analyze_drug_distribution_for_diagnosis_issue(clean_df)
    
    # 创建transmitReason分布图表
    plt.figure(figsize=(16, 10))
    
    # 获取前8个最常见的原因，其余合并为"其他"
    top_reasons = reason_counter.most_common(10)
    reasons = [item[0] for item in top_reasons]
    counts = [item[1] for item in top_reasons]
    
    # 计算其他类别的总数
    other_count = sum(count for reason, count in reason_counter.most_common()[10:])
    if other_count > 0:
        reasons.append('其他')
        counts.append(other_count)
    
    # 创建饼图，使用更好的标签处理
    plt.subplot(2, 1, 1)
    
    # 为了避免标签重叠，对较长的标签进行换行处理
    wrapped_reasons = []
    for reason in reasons:
        if len(reason) > 15:
            # 将长标签按15个字符换行
            words = reason
            if len(words) > 15:
                mid = len(words) // 2
                wrapped_reasons.append(words[:mid] + '\n' + words[mid:])
            else:
                wrapped_reasons.append(words)
        else:
            wrapped_reasons.append(reason)
    
    # 设置颜色
    colors = plt.cm.Set3(range(len(counts)))
    
    wedges, texts, autotexts = plt.pie(counts, labels=wrapped_reasons, autopct='%1.1f%%', 
                                      startangle=90, colors=colors,
                                      textprops={'fontsize': 10, 'fontweight': 'bold'},
                                      pctdistance=0.85)
    
    # 调整标签位置避免重叠
    for autotext in autotexts:
        autotext.set_color('white')
        autotext.set_fontweight('bold')
        autotext.set_fontsize(9)
    
    plt.title('不同 transmitReason 的比例分布', fontsize=16, fontweight='bold', pad=20)
    
    # 创建柱状图
    plt.subplot(2, 1, 2)
    bars = plt.barh(wrapped_reasons, counts, color=colors)
    
    # 在每个条形上添加数值标签
    for i, (bar, count) in enumerate(zip(bars, counts)):
        plt.text(count + max(counts) * 0.01, i, f'{count}', 
                va='center', ha='left', fontweight='bold')
    
    plt.xlabel('次数', fontsize=12, fontweight='bold')
    plt.title('不同 transmitReason 的数量统计', fontsize=16, fontweight='bold', pad=20)
    plt.gca().invert_yaxis()  # 反转y轴，使最高的在顶部
    
    # 设置x轴格式
    plt.ticklabel_format(style='plain', axis='x')
    plt.grid(axis='x', alpha=0.3)
    
    # 调整布局
    plt.tight_layout()
    
    # 保存图表
    plt.savefig('transmit_reason_analysis.png', dpi=300, bbox_inches='tight')
    print("\n图表已保存为 'transmit_reason_analysis.png'")
    
    # 显示图表
    plt.show()
    
    # 保存详细统计结果到文件
    with open('transmit_reason_stats.txt', 'w', encoding='utf-8') as f:
        f.write("transmitReason 统计分析结果\n")
        f.write("=" * 50 + "\n\n")
        f.write(f"原始数据量: {len(df)} 行\n")
        f.write(f"提取有效数据: {len(extracted_data)} 条\n")
        f.write(f"清洗后数据量: {len(clean_df)} 条\n")
        f.write(f"有效transmitReason数量: {len(transmit_reasons)} 个\n")
        f.write(f"不同transmitReason类型数量: {len(reason_counter)} 种\n\n")
        f.write("详细统计:\n")
        f.write("-" * 30 + "\n")
        
        for reason, count in reason_counter.most_common():
            percentage = (count / len(transmit_reasons)) * 100
            f.write(f"{reason}: {count} 次 ({percentage:.1f}%)\n")
    
    print("详细统计结果已保存为 'transmit_reason_stats.txt'")
    
    # 发送分析结果到企业微信群
    webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4c6cc249-3646-4990-8c11-71e182256f44"
    
    print("\n" + "="*60)
    print("📤 开始发送分析结果到企业微信群...")
    print("="*60)
    
    # 发送总结文本消息
    summary_text = f"""📊 数据分析报告

📈 数据概览:
• 原始数据: {len(df):,} 行
• 有效数据: {len(extracted_data):,} 条
• 清洗后数据: {len(clean_df):,} 条

🔝 Top 3 transmitReason:
1. {reason_counter.most_common(3)[0][0]}: {reason_counter.most_common(3)[0][1]:,}次 ({reason_counter.most_common(3)[0][1]/len(transmit_reasons)*100:.1f}%)
2. {reason_counter.most_common(3)[1][0]}: {reason_counter.most_common(3)[1][1]:,}次 ({reason_counter.most_common(3)[1][1]/len(transmit_reasons)*100:.1f}%)
3. {reason_counter.most_common(3)[2][0]}: {reason_counter.most_common(3)[2][1]:,}次 ({reason_counter.most_common(3)[2][1]/len(transmit_reasons)*100:.1f}%)

📋 已生成详细分析图表和报告文件"""
    
    send_text_to_wechat_webhook(summary_text, webhook_url)
    
    # 发送分析图表
    images_to_send = [
        ("transmit_reason_analysis.png", "TransmitReason分布分析图表"),
        ("doctor_analysis_chart.png", "医生账号分布分析图表"),
        ("risk_drug_analysis_chart.png", "风险检测不通过-药品分布图表"),
        ("diagnosis_drug_analysis_chart.png", "诊断问题-药品分布图表")
    ]
    
    for image_path, description in images_to_send:
        try:
            import os
            if os.path.exists(image_path):
                print(f"📤 发送图表: {description}")
                send_image_to_wechat_webhook(image_path, webhook_url, description)
            else:
                print(f"⚠️  图表文件不存在: {image_path}")
        except Exception as e:
            print(f"❌ 处理图表 {image_path} 时出错: {e}")
    
    print("\n✅ 分析完成！所有结果已发送到企业微信群。")

if __name__ == "__main__":
    main()
